// 对于axios进行二次封装
import axios from 'axios'
import store from '@/store'
import { Loading } from 'element-ui'
let loading
// 引入进度条
// import nprogress from 'nprogress';
// 设置进度条样式
// import 'nprogress/nprogress.css';

// 1. 利用axios对象的方法create，去创建一个axios实例
// 2. request就是axios，只不过稍微配置一下
axios.defaults.withCredentials = true //允许跨域
//Content-Type 响应头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
axios.defaults.headers.common['Authorization'] = window.localStorage.token
const requests = axios.create({
	// 配置对象
	//baseURL: 'http://43.139.170.65:9090',
	 baseURL: 'http://localhost:9090',
	// 代表请求超时的时间5s

	timeout: 5000
})
function generateReqKey(config) {
	const { method, url, params, data } = config
	return [method, url, JSON.stringify(params), JSON.stringify(data)].join('&')
}
const pendingRequest = new Map()
function addPendingRequest(config) {
	const requestKey = generateReqKey(config)
	config.cancelToken =
		config.cancelToken ||
		new axios.CancelToken((cancel) => {
			if (!pendingRequest.has(requestKey)) {
				pendingRequest.set(requestKey, cancel)
			}
		})
}
function removePendingRequest(config) {
	const requestKey = generateReqKey(config)
	if (pendingRequest.has(requestKey)) {
		const cancelToken = pendingRequest.get(requestKey)
		cancelToken(requestKey)
		pendingRequest.delete(requestKey)
	}
}
function clearPending() {
	for (const [requestKey, cancelToken] of pendingRequest) {
		cancelToken(requestKey)
	}
	pendingRequest.clear()
}

function startLoading() {
	// 开始加载动画
	loading = Loading.service({
		lock: true,
		text: '加载中...',
		background: 'rgba(0, 0, 0, 0)'
	})
}

function endLoading() {
	//  关闭加载动画
	loading.close()
}

// 请求拦截器:发请求之前,请求拦截器可以检测到,可以在请求发出去之前做一些事情
requests.interceptors.request.use(
	(config) => {
		startLoading() //  打开加载动画
		// config:配置对象,对象里面有一个属性很重要:headers请求头
		removePendingRequest(config) // 检查是否存在重复请求，若存在则取消已发的请求
		addPendingRequest(config) // 把当前请求信息添加到pendingRequest对象中
		 //config.headers['Content-Type'] = 'application/json;charset=utf-8';
		const tokenStr = localStorage.getItem('token')
		// const tokenStr = window.localStorage.token
		if (tokenStr) {
			config.headers.Authorization = tokenStr
		}
		// config.headers['access-token'] = localStorage.getItem('token');
		// this.$store.state.car.list
		return config
	},
	(error) => {
		// 这里出现错误可能是网络波动造成的，清空 pendingRequests 对象
		pendingRequests.clear()
		return Promise.reject(error)
	}
)

// 响应的拦截器
requests.interceptors.response.use(
	(response) => {
		endLoading() //  关闭加载动画
		// 进度条结束
		// 成功的回调函数:服务器相应数据回来以后,响应拦截器可以检测到，可以做一些事情
		removePendingRequest(response.config) // 从pendingRequest对象中移除请求
		let res = response.data
		// res里面包含了code data msg这三个属性
		// 如果返回的结果是一个String 先解析再返回
		if (typeof res === 'string') {
			res = res ? JSON.parse(res) : res
		}
		return res
	},
	(error) => {
		endLoading() //  关闭加载动画
		removePendingRequest(error.config || {}) // 从pendingRequest对象中移除请求
		if (axios.isCancel(error)) {
			console.warn(error)
			return Promise.reject(error)
		} else {
			// 添加其它异常处理
		}
		// 相应失败的回调函数
		return Promise.reject(new Error('faile你失败了' + error))
	}
)

// 对外暴露
export default requests
